package vista.paneles;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import javax.swing.ImageIcon;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.MutableTreeNode;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;

import logica.Atributo;
import logica.Entidad;
import logica.Identificador;

@SuppressWarnings("serial")
public class TreeDeIdentificadores extends JTree {
	
	private static final String PATH_IMAGEN_HOJA = "../imagenes/atributoSimple.png";
	private static final String PATH_IMAGEN_ABIERTO = "../imagenes/atributoCompuesto.png";
	
	private DefaultTreeModel modeloArbol;
	private DefaultMutableTreeNode raiz;
	
	public TreeDeIdentificadores(DefaultMutableTreeNode raiz)
	{
		super(new DefaultTreeModel(raiz));

		this.modeloArbol = (DefaultTreeModel) this.getModel();
		this.raiz = raiz;

		((DefaultTreeCellRenderer)this.getCellRenderer()).setLeafIcon(new ImageIcon(getClass().getResource(PATH_IMAGEN_HOJA)));
		((DefaultTreeCellRenderer)this.getCellRenderer()).setOpenIcon(new ImageIcon(getClass().getResource(PATH_IMAGEN_ABIERTO)));
		((DefaultTreeCellRenderer)this.getCellRenderer()).setClosedIcon(new ImageIcon(getClass().getResource(PATH_IMAGEN_ABIERTO)));

		this.setRootVisible(false);
		this.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
	   
		TreePath parentPath = this.getSelectionPath();
	    this.expandPath(parentPath);
	    
	}
	
	public int getCantidadDeIdentificador()
	{
		return this.raiz.getChildCount();
	}
	
	public void agregarIdentificador(Identificador identificador)
	{	
		DefaultMutableTreeNode nodoNombre = new DefaultMutableTreeNode(identificador);
		this.modeloArbol.insertNodeInto(nodoNombre, raiz, raiz.getChildCount());
		this.expandPath(new TreePath(raiz));

		agregarAtributoAlArbol(identificador.getAtributos(), nodoNombre);
		agregarEntidadesAlArbol(identificador.getEntidades(), nodoNombre);
	}

	private void agregarAtributoAlArbol(List<Atributo> atributos, DefaultMutableTreeNode nodoPadre)
	{
		if (atributos.isEmpty())
			return;
			
		DefaultMutableTreeNode nodoPadreAtributo = new DefaultMutableTreeNode("id Internos");
		this.modeloArbol.insertNodeInto(nodoPadreAtributo, nodoPadre, nodoPadre.getChildCount());
		this.expandPath(new TreePath(nodoPadre));
		
		Iterator<Atributo> iterAtributo = atributos.iterator();
		
		while (iterAtributo.hasNext())
			this.agregarObjetoAlArbol(iterAtributo.next(), nodoPadreAtributo);
	}

	private void agregarEntidadesAlArbol(List<Entidad> entidades, DefaultMutableTreeNode nodoPadre)
	{
		if (entidades.isEmpty())
			return;
	 
		DefaultMutableTreeNode nodoPadreEntidad = new DefaultMutableTreeNode("id Externos");
		
		this.modeloArbol.insertNodeInto(nodoPadreEntidad, nodoPadre, nodoPadre.getChildCount());
		this.expandPath(new TreePath(nodoPadre));

		Iterator<Entidad> iterEntidad = entidades.iterator();
		
		while (iterEntidad.hasNext())
			this.agregarObjetoAlArbol(iterEntidad.next(), nodoPadreEntidad);
	}
	
	private void agregarObjetoAlArbol(Object objeto, DefaultMutableTreeNode nodoPadre)
	{
		DefaultMutableTreeNode nodoHijo = new DefaultMutableTreeNode(objeto);

        this.modeloArbol.insertNodeInto(nodoHijo, nodoPadre, nodoPadre.getChildCount());
        this.expandPath(new TreePath(nodoPadre));
	}
	
	public void quitarIdentificador() throws NoEsNodoPadre
	{	
		TreePath currentSelection =  this.getSelectionPath();
			    
		if (currentSelection != null)
		{
			DefaultMutableTreeNode currentNode = (DefaultMutableTreeNode)(currentSelection.getLastPathComponent());
			MutableTreeNode parent = (MutableTreeNode)(currentNode.getParent());
			
			if (currentNode.getLevel() != 1)
				throw new NoEsNodoPadre("Para borrar un Identificador debe seleccionar la clave.");

			if (parent != null)
			{
				modeloArbol.removeNodeFromParent(currentNode);
				return;
			}
		}
	}
	
	public List<Identificador> getIdentificadores()
	{
		List<Identificador> objetos = new LinkedList<Identificador>();
		
		int nroElemento = 0;
		while (nroElemento < this.modeloArbol.getChildCount(raiz))
		{
			DefaultMutableTreeNode nodo = (DefaultMutableTreeNode)this.modeloArbol.getChild(raiz, nroElemento); 
			objetos.add((Identificador)nodo.getUserObject());
			nroElemento++;
		}
		
		return objetos;
	}

}
